#include "led.h"
#include "pico/stdlib.h"
#include "hardware/gpio.h"
#include <stdio.h>
#include "LOG.h"
#include "board.h"

// 定义RGB LED的GPIO引脚
#define LED_RED_PIN LED1_PIN
#define LED_GREEN_PIN LED2_PIN
#define LED_BLUE_PIN LED3_PIN

static uint32_t ui32LedOnTime = 1000;
static uint32_t ui32LedOffTime = 2000;
static uint32_t ui32LedOnOffTick = 0;
static bool bLedIsOn = false;
static bool holdon = true;
static uint32_t ui32LedCtrlTime = 300000;
static uint32_t ui32LedCtrlTick = 0;
static SYSTEM_LED_TYPE currentLedType = SYSTEM_LED_TYPE_NONE;
static SYSTEM_LED_TYPE preLedType = SYSTEM_LED_TYPE_NONE;
static uint8_t preindex = SYSTEM_TERMINATE, curindex = SYSTEM_TERMINATE, maxindex = SYSTEM_TERMINATE;

static void LedErrorWarning(void);
static void LedPowerLowWarning(void);
static void LedCharging(void);
static void LedChargeOver(void);
static void LedNormal(void);
static void LedLeadoff(void);
static void LedLowPower(void);
static void LedOad(void);
static void LedRepeat(void);

static volatile LED_STRUCT ledTable[] = {
    // onTime offTime controlLimit   noLimit	pLedFunc
    {200, 800, 300000, false, LedNormal},         // 8ms or 20ms
    {200, 200, 90000, false, LedLeadoff},         // 8ms or 20ms
    {200, 200, 300000, false, LedRepeat},         // 8ms
    {200, 200, 60000, false, LedPowerLowWarning}, // 8ms or 20ms or 1000ms
    {0, 0, 0, false, LedLowPower},                // 1000ms off continuous
    {500, 500, ~0, true, LedCharging},            // 8ms or 20ms
    {~0, 0, ~0, true, LedChargeOver},             // 8ms or 20ms
    {50, 50, ~0, true, LedOad},                   // 8ms
    {~0, 0, 300000, false, LedErrorWarning},      // 8ms or 20ms or 1000ms
};

// LED GPIO初始化
void led_gpio_init(void)
{
    LOG_INFO("led_gpio_init - Initializing GPIO pins");
    LOG_INFO("  - Configuring LED_RED_PIN %d as output, initial state HIGH", LED_RED_PIN);
    gpio_init(LED_RED_PIN);
    gpio_set_dir(LED_RED_PIN, GPIO_OUT);
    gpio_put(LED_RED_PIN, 0);

    LOG_INFO("  - Configuring LED_GREEN_PIN %d as output, initial state HIGH", LED_GREEN_PIN);
    gpio_init(LED_GREEN_PIN);
    gpio_set_dir(LED_GREEN_PIN, GPIO_OUT);
    gpio_put(LED_GREEN_PIN, 0);

    LOG_INFO("  - Configuring LED_BLUE_PIN %d as output, initial state HIGH", LED_BLUE_PIN);
    gpio_init(LED_BLUE_PIN);
    gpio_set_dir(LED_BLUE_PIN, GPIO_OUT);
    gpio_put(LED_BLUE_PIN, 0);

    LOG_INFO("led_gpio_init completed successfully");
}

void BOARD_RedLedOff(void)
{
    gpio_put(LED_RED_PIN, 0);  // RP2040中1表示高电平，LED熄灭
}

void BOARD_GreenLedOff(void)
{
    gpio_put(LED_GREEN_PIN, 0);  // RP2040中1表示高电平，LED熄灭
}

void BOARD_BlueLedOff(void)
{
    gpio_put(LED_BLUE_PIN, 0);  // RP2040中1表示高电平，LED熄灭
}

void BOARD_RedLedOn(void)
{
    gpio_put(LED_RED_PIN, 1);  // RP2040中0表示低电平，LED点亮
}

void BOARD_GreenLedOn(void)
{
    gpio_put(LED_GREEN_PIN, 1);  // RP2040中0表示低电平，LED点亮
}

void BOARD_BlueLedOn(void)
{
    gpio_put(LED_BLUE_PIN, 1);  // RP2040中0表示低电平，LED点亮
}

void RedLedToggle()
{
    // 获取当前LED状态并切换
    bool current_state = gpio_get(LED_RED_PIN);
    gpio_put(LED_RED_PIN, !current_state);
}

void GreenLedToggle()
{
    // 获取当前LED状态并切换
    bool current_state = gpio_get(LED_GREEN_PIN);
    gpio_put(LED_GREEN_PIN, !current_state);
}

void BlueLedToggle()
{
    // 获取当前LED状态并切换
    bool current_state = gpio_get(LED_BLUE_PIN);
    gpio_put(LED_BLUE_PIN, !current_state);
}

void LedHandleRegister(LED_ID id)
{
    curindex = id;
    if (curindex > maxindex)
    {
        maxindex = curindex;
    }
    else
    {
        curindex = maxindex;
    }
}

uint8_t LedGetSystemStat()
{
    return curindex;
}

void LedTimeInit(SYSTEM_LED_TYPE type, LED_ID led_id)
{
    currentLedType = type;
    ui32LedOnTime = ledTable[led_id].onTime;
    ui32LedOffTime = ledTable[led_id].offTime;
    ui32LedCtrlTime = ledTable[led_id].controlLimit;
    holdon = ledTable[led_id].noLimit;
    if (bLedIsOn)
    {
        bLedIsOn = false;
    }
}

void LedHandleProcess()
{
    if (curindex != SYSTEM_TERMINATE)
    {
        if (preindex != curindex)
        {
            ledTable[curindex].pLedFunc();
            preindex = curindex;
            ui32LedCtrlTick = 0;
            ui32LedOnOffTick = 0;
        }
    }

    if (curindex != SYSTEM_DEVICE_INIT_ERROR)
    {
        curindex = SYSTEM_TERMINATE;
        maxindex = 0;
    }
}

static void LedErrorWarning(void)
{
    LedTimeInit(SYSTEM_LED_TYPE_RED, SYSTEM_DEVICE_INIT_ERROR);
}

static void LedPowerLowWarning(void)
{
    LedTimeInit(SYSTEM_LED_TYPE_RED, SYSTEM_POWER_LOW);
}

static void LedCharging(void)
{
    LedTimeInit(SYSTEM_LED_TYPE_BLUE, SYSTEM_CHARGING);
}

static void LedChargeOver(void)
{
    LedTimeInit(SYSTEM_LED_TYPE_BLUE, SYSTEM_CHARGEOVER);
}
static void LedRepeat(void)
{
    LedTimeInit(SYSTEM_LED_TYPE_BLUE, SYSTEM_REPEAT);
}

static void LedNormal(void)
{
    LedTimeInit(SYSTEM_LED_TYPE_GREEN, SYSTEM_NORMAL);
}
static void LedLeadoff(void)
{
    LedTimeInit(SYSTEM_LED_TYPE_GREEN, SYSTEM_LEADOFF);
}

static void LedLowPower(void)
{
    LedTimeInit(SYSTEM_LED_TYPE_GREEN, SYSTEM_LOWPOWER);
}
static void LedOad(void)
{
    LedTimeInit(SYSTEM_LED_TYPE_GREEN, SYSTEM_OAD);
}

bool LedSingleControl(uint16_t millisec, bool bcloseall)
{
    if (bcloseall)
    {
        BOARD_RedLedOff();
        BOARD_GreenLedOff();
        BOARD_BlueLedOff();
        ui32LedCtrlTick = 0;
        ui32LedOnOffTick = 0;
        bLedIsOn = false;
    }

    ui32LedCtrlTick += millisec;
    
    if (ui32LedCtrlTick >= ui32LedCtrlTime)
    {
        if (holdon == false)
        {
            ui32LedCtrlTick = ui32LedCtrlTime;
            if (curindex == SYSTEM_DEVICE_INIT_ERROR)
            {
                curindex = SYSTEM_TERMINATE;
                maxindex = 0;
            }
            LEDonoff(preLedType, false);
            return true;
        }
        else
        {
            ui32LedCtrlTick = 0;
        }
    }

    if (currentLedType != preLedType)
    {
        LEDonoff(preLedType, false);
        bLedIsOn = false;
        preLedType = currentLedType;
    }

    ui32LedOnOffTick += millisec;
    if (bLedIsOn)
    {
        if (ui32LedOnOffTick >= ui32LedOnTime)
        {
            switch (currentLedType)
            {
            case SYSTEM_LED_TYPE_RED:
                BOARD_RedLedOff();
                bLedIsOn = false;
                ui32LedOnOffTick = 0;
                break;
            case SYSTEM_LED_TYPE_GREEN:
                BOARD_GreenLedOff();
                bLedIsOn = false;
                ui32LedOnOffTick = 0;
                break;
            case SYSTEM_LED_TYPE_BLUE:
                BOARD_BlueLedOff();
                bLedIsOn = false;
                ui32LedOnOffTick = 0;
                break;
            default:
                break;
            }
        }
    }
    else
    {
        if (ui32LedOnOffTick >= ui32LedOffTime)
        {
            switch (currentLedType)
            {
            case SYSTEM_LED_TYPE_RED:
                BOARD_RedLedOn();
                bLedIsOn = true;
                ui32LedOnOffTick = 0;
                break;
            case SYSTEM_LED_TYPE_GREEN:
                BOARD_GreenLedOn();
                bLedIsOn = true;
                ui32LedOnOffTick = 0;
                break;
            case SYSTEM_LED_TYPE_BLUE:
                BOARD_BlueLedOn();
                bLedIsOn = true;
                ui32LedOnOffTick = 0;
                break;
            default:
                break;
            }
        }
    }
    return true;
}


void LEDonoff(uint8_t led_type, bool onoff)
{
    if (onoff == false)
    {
        if (led_type & SYSTEM_LED_TYPE_RED)
        {
            BOARD_RedLedOff();
        }
        if (led_type & SYSTEM_LED_TYPE_GREEN)
        {
            BOARD_GreenLedOff();
        }
        if (led_type & SYSTEM_LED_TYPE_BLUE)
        {
            BOARD_BlueLedOff();
        }
    }
    else
    {
        if (led_type & SYSTEM_LED_TYPE_RED)
        {
            BOARD_RedLedOn();
        }
        if (led_type & SYSTEM_LED_TYPE_GREEN)
        {
            BOARD_GreenLedOn();
        }
        if (led_type & SYSTEM_LED_TYPE_BLUE)
        {
            BOARD_BlueLedOn();
        }
    }
}

void BOARD_LEDtest()
{
    // 红色LED测试
    BOARD_RedLedOn();
    sleep_ms(500);
    BOARD_RedLedOff();

    // 绿色LED测试
    BOARD_GreenLedOn();
    sleep_ms(500);
    BOARD_GreenLedOff();

    // 蓝色LED测试
    BOARD_BlueLedOn();
    sleep_ms(500);
    BOARD_BlueLedOff();
}
